﻿//
// Copyright 2024 Exhunter Technology Co.Ltd2.
//

using System;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;

namespace X18.Framework.Core.Security.Encryptor
{
    /// <summary>
    /// AES加密算法
    /// </summary>
    public class AesEncryptor : IDataEncryptor
    {
        /// <summary>
        /// 默认SecretKey
        /// </summary>
        private static readonly byte[] DefalutSecretKey = { 0x3A, 0x7F, 0xD2, 0x2E, 0x9B, 0xF1, 0x6C, 0xA5, 0x83, 0x48, 0xE7, 0x1D, 0xC4, 0x59, 0xB6, 0x00F };

        public override byte[] EncryptToBytes(byte[] plainBytes, byte[] key = null)
        {
            // 初始化IV
            byte[] iv = new byte[16];
            SecureRandom random = new SecureRandom();
            random.NextBytes(iv);
            // 加密
            byte[] key0 = key ?? DefalutSecretKey;
            byte[] buffer = Encrypt(plainBytes, key0, iv);
            byte[] result = new byte[key0.Length + buffer.Length];
            Array.Copy(iv, 0, result, 0, iv.Length);
            Array.Copy(buffer, 0, result, key0.Length, buffer.Length);
            return result;
        }

        public override byte[] DecryptFromBytes(byte[] cipherBytes, byte[] key = null)
        {
            // 初始化IV
            byte[] iv = new byte[16];
            byte[] buffer = new byte[cipherBytes.Length - iv.Length];
            Array.Copy(cipherBytes, 0, iv, 0, iv.Length);
            Array.Copy(cipherBytes, iv.Length, buffer, 0, buffer.Length);
            // 解密
            byte[] key0 = key ?? DefalutSecretKey;
            byte[] result = Decrypt(buffer, key0, iv);
            return result;
        }

        /// <summary>
        /// 加密
        /// </summary>
        public static byte[] Encrypt(byte[] plainText, byte[] key, byte[] iv)
        {
            IBufferedCipher cipher = CipherUtilities.GetCipher("AES/CBC/PKCS7Padding");
            cipher.Init(true, new ParametersWithIV(ParameterUtilities.CreateKeyParameter("AES", key), iv));
            // 加密
            var cipherText = cipher.DoFinal(plainText);
            // 返回密文
            return cipherText;
        }

        /// <summary>
        /// 解密
        /// </summary>
        public static byte[] Decrypt(byte[] cipherText, byte[] key, byte[] iv)
        {
            IBufferedCipher cipher = CipherUtilities.GetCipher("AES/CBC/PKCS7Padding");
            cipher.Init(false, new ParametersWithIV(ParameterUtilities.CreateKeyParameter("AES", key), iv));
            // 解密
            var recoveredText = cipher.DoFinal(cipherText);
            // 返回明文
            return recoveredText;
        }
    }
}
